#include "table-manager.h"

#define SOFTWARE_DB_DIR "/usr/software/database/ir-software.db"

db_table_manager::db_table_manager()
    : mi_connect_id(0)
{
    memset( mst_config_table, 0x00, sizeof(mst_config_table) );
}

db_table_manager::~db_table_manager()
{

}

bool db_table_manager::init()
{
    if( !init_db_file() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "initialize database failed.\n" );
        close_all_databases();
        return false;
    }

    std::list<st_preset_onfig_table_item> PresetConfigList;
    get_preset_config_handler()->copy_list(PresetConfigList, true);
    if(PresetConfigList.size() < 255){
#ifdef VERSION_HIKVISION_PTZ
        for(int i = 1; i <= 255; i++){
            std::string str_preset_name = "Preset-" + std::to_string(i);
            unsigned int ui_no = i;
            unsigned int ui_used = 0;
            bool b_has = get_preset_config_handler()->get_preset_used(ui_no, ui_used);
            if(!b_has){
                get_preset_config_handler()->add_preset(i, str_preset_name, 0);
            }
        }
#endif

#ifdef PTZ_SUER_SUPPORT
        for(int i = 1; i <= 255; i++){
            std::string str_preset_name;
            if(i == 34){
                str_preset_name = "Go Home";
            } else if(i == 94){
                str_preset_name = "Reboot System";
            } else {
                str_preset_name = "Preset-" + convert_to_string(i);
            }

            if( (i == 34) || (i == 94)){
                get_preset_config_handler()->add_preset(i, str_preset_name, 1);
            } else {
                get_preset_config_handler()->add_preset(i, str_preset_name, 0);
            }
        }
#endif
    }

    return true;
}

bool db_table_manager::init_db_file()
{
    if(mst_config_table[BASIC_INFORMATION_TABLE] != NULL && mst_config_table[OSD_CONFIG_TABLE] != NULL) {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "tables has been initialized.\n");
        return true;
    }

    std::string str_db_path = SOFTWARE_DB_DIR;
    std::string::size_type pos = str_db_path.rfind( '/' );
    if( pos != std::string::npos ){
        std::string str_path = str_db_path.substr( 0, pos );
        CreatePath( str_path );
    }

    int i_connect_id = SQLITE_INVAILD_CONNECTID;
    i_connect_id = connect_db_file(str_db_path);
    if(i_connect_id == SQLITE_INVAILD_CONNECTID){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "connect_db %s failed.\n", str_db_path.c_str() );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "database connect finished.\n");

    sql_executor_cmd* p_excutor = get_db_executor(i_connect_id);
    if(p_excutor == NULL) {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "connect excutor NULL error.\n");
        return false;
    }

    st_sql_table_info table_info;

    //-----------------------------------BASIC_INFORMATION_TABLE----------------------------------------------------
    table_basic_config_handler* basic_config_handler = new table_basic_config_handler;
    mst_config_table[BASIC_INFORMATION_TABLE] = basic_config_handler;
    basic_config_handler->set_connect_id(i_connect_id);
    basic_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    basic_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table info check Failed. tableId = %d\n", BASIC_INFORMATION_TABLE);
        return false;
    }

    int i_ret = basic_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", BASIC_INFORMATION_TABLE, i_ret );
        return false;
    }

    if( !basic_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", BASIC_INFORMATION_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create basic table finish.\n");

    //-----------------------------------OSD_CONFIG_TABLE----------------------------------------------------
    table_osd_config_handler* osd_config_handler = new table_osd_config_handler;
    mst_config_table[OSD_CONFIG_TABLE] = osd_config_handler;
    osd_config_handler->set_connect_id(i_connect_id);
    osd_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    osd_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", OSD_CONFIG_TABLE);
        return false;
    }

    i_ret = osd_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", OSD_CONFIG_TABLE, i_ret );
        return false;
    }
    if( !osd_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", OSD_CONFIG_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create osd table finish.\n");

    //-----------------------------------PRESET_TABLE----------------------------------------------------
    table_preset_config_handler* preset_config_handler = new table_preset_config_handler;
    mst_config_table[PRESET_TABLE] = preset_config_handler;
    preset_config_handler->set_connect_id(i_connect_id);
    preset_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    preset_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table info check Failed. tableId = %d\n", PRESET_TABLE);
        return false;
    }

    i_ret = preset_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", PRESET_TABLE, i_ret );
        return false;
    }

    if( !preset_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", PRESET_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create preset table finish.\n");

    //-----------------------------------PGUSER_TABLE----------------------------------------------------
    table_pg_user_manager_handler* pguser_config_handler = new table_pg_user_manager_handler;
    mst_config_table[PGUSER_TABLE] = pguser_config_handler;
    pguser_config_handler->set_connect_id(i_connect_id);
    pguser_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    pguser_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table info check Failed. tableId = %d\n", PGUSER_TABLE);
        return false;
    }

    i_ret = pguser_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", PGUSER_TABLE, i_ret );
        return false;
    }

    if( !pguser_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", PGUSER_TABLE );
        return false;
    }    

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create pguser table finish.\n");

    //-----------------------------------ONVIFUSER_TABLE----------------------------------------------------
    table_onvif_user_manager_handler* onvifuser_config_handler = new table_onvif_user_manager_handler;
    mst_config_table[ONVIFUSER_TABLE] = onvifuser_config_handler;
    onvifuser_config_handler->set_connect_id(i_connect_id);
    onvifuser_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    onvifuser_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table info check Failed. tableId = %d\n", ONVIFUSER_TABLE);
        return false;
    }

    i_ret = onvifuser_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", ONVIFUSER_TABLE, i_ret );
        return false;
    }

    if( !onvifuser_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", ONVIFUSER_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create onvifuser table finish.\n");

    //-----------------------------------PG_OSD_TABLE----------------------------------------------------
    table_pg_osd_config_handler* pg_osd_config_handler = new table_pg_osd_config_handler;
    mst_config_table[PG_OSD_TABLE] = pg_osd_config_handler;
    pg_osd_config_handler->set_connect_id(i_connect_id);
    pg_osd_config_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    pg_osd_config_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", PG_OSD_TABLE);
        return false;
    }

    i_ret = pg_osd_config_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", PG_OSD_TABLE, i_ret );
        return false;
    }
    if( !pg_osd_config_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", PG_OSD_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create pg osd table finish.\n");

    //-----------------------------------PGLOGMANAGER_TABLE----------------------------------------------------
    table_pg_log_manager_handler* pg_log_manager_handler = new table_pg_log_manager_handler;
    mst_config_table[PGLOGMANAGER_TABLE] = pg_log_manager_handler;
    pg_log_manager_handler->set_connect_id(i_connect_id);
    pg_log_manager_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    pg_log_manager_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", PGLOGMANAGER_TABLE);
        return false;
    }

    i_ret = pg_log_manager_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", PGLOGMANAGER_TABLE, i_ret );
        return false;
    }
    if( !pg_log_manager_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", PGLOGMANAGER_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create pg log manager table finish.\n");

    //-----------------------------------VIDEO_RECORDFILE_TABLE----------------------------------------------------
    table_video_record_file_handler* p_video_record_file_handler = new table_video_record_file_handler;
    mst_config_table[VIDEO_RECORDFILE_TABLE] = p_video_record_file_handler;
    p_video_record_file_handler->set_connect_id(i_connect_id);
    p_video_record_file_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    p_video_record_file_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", VIDEO_RECORDFILE_TABLE);
        return false;
    }

    i_ret = p_video_record_file_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", VIDEO_RECORDFILE_TABLE, i_ret );
        return false;
    }
    if( !p_video_record_file_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", VIDEO_RECORDFILE_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create video record file table finish.\n");

    //-----------------------------------JPG_RECORDFILE_TABLE----------------------------------------------------
    table_picture_record_file_handler* p_picture_record_file_handler = new table_picture_record_file_handler;
    mst_config_table[JPG_RECORDFILE_TABLE] = p_picture_record_file_handler;
    p_picture_record_file_handler->set_connect_id(i_connect_id);
    p_picture_record_file_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    p_picture_record_file_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", JPG_RECORDFILE_TABLE);
        return false;
    }

    i_ret = p_picture_record_file_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", JPG_RECORDFILE_TABLE, i_ret );
        return false;
    }
    if( !p_picture_record_file_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", JPG_RECORDFILE_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create picture record file table finish.\n");

    //-----------------------------------USER_MANAGER_TABLE----------------------------------------------------
    table_user_manager_handler* p_user_manager_handler = new table_user_manager_handler;
    mst_config_table[USER_MANAGER_TABLE] = p_user_manager_handler;
    p_user_manager_handler->set_connect_id(i_connect_id);
    p_user_manager_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    p_user_manager_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", USER_MANAGER_TABLE);
        return false;
    }

    i_ret = p_user_manager_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", USER_MANAGER_TABLE, i_ret );
        return false;
    }
    if( !p_user_manager_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", USER_MANAGER_TABLE );
        return false;
    }

    //-----------------------------------PRESET_TEXT_TABLE----------------------------------------------------
    table_preset_text_handler* p_preset_text_handler = new table_preset_text_handler;
    mst_config_table[PRESET_TEXT_TABLE] = p_preset_text_handler;
    p_preset_text_handler->set_connect_id(i_connect_id);
    p_preset_text_handler->set_connect_excutor(p_excutor);
    table_info.str_table_name = "";
    table_info.col_info_list.clear();
    p_preset_text_handler->get_table_info( table_info );
    if( !check_table_info( i_connect_id, table_info ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "table_verify Failed. tableId = %d\n", PRESET_TEXT_TABLE);
        return false;
    }

    i_ret = p_preset_text_handler->load_from_db();
    if( i_ret != TableError_OK ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db Failed. tableId=%d, ret=%d\n", PRESET_TEXT_TABLE, i_ret );
        return false;
    }
    if( !p_preset_text_handler->check_table_default_data() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "check table data Failed. tableId=%d\n", PRESET_TEXT_TABLE );
        return false;
    }

    HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load or create preset text table finish.\n");
    //-----------------------------------init all table over----------------------------------------------------
    return true;
}

int db_table_manager::connect_db_file( std::string &str_db_path, bool b_create )
{
    if( str_db_path.empty() ){
        return SQLITE_INVAILD_CONNECTID;
    }

    st_db_connect_info connect_info;
    connect_info.str_db_name = str_db_path;
    connect_info.p_db_executor = new sql_executor_cmd();

    if( !connect_info.p_db_executor ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "create connect failed.\n" );
        return SQLITE_INVAILD_CONNECTID;
    }

    if( !connect_info.p_db_executor->open( connect_info.str_db_name, b_create ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "open db failed.\n" );
        return SQLITE_INVAILD_CONNECTID;
    }

    if( !connect_info.p_db_executor->get_db_table_info( connect_info.db_table_info_list ) ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "get dbinfo failed.\n" );
        return SQLITE_INVAILD_CONNECTID;
    }

    std::lock_guard<std::mutex> guard(m_connect_lock);
    mi_connect_id++;
    m_connect_info_map[mi_connect_id] = connect_info;

    return mi_connect_id;
}

table_basic_config_handler* db_table_manager::get_basic_config_handler() {
    return (table_basic_config_handler*)mst_config_table[BASIC_INFORMATION_TABLE];
}

table_osd_config_handler* db_table_manager::get_osd_config_handler() {
    return (table_osd_config_handler*)mst_config_table[OSD_CONFIG_TABLE];
}

table_preset_config_handler* db_table_manager::get_preset_config_handler() {
    return (table_preset_config_handler*)mst_config_table[PRESET_TABLE];
}

table_pg_user_manager_handler *db_table_manager::get_pg_user_manager_config_handler()
{
    return (table_pg_user_manager_handler*)mst_config_table[PGUSER_TABLE];
}

table_onvif_user_manager_handler *db_table_manager::get_onvif_user_manager_config_handler()
{
    return (table_onvif_user_manager_handler*)mst_config_table[ONVIFUSER_TABLE];
}

table_pg_osd_config_handler *db_table_manager::get_pg_osd_config_handler()
{
    return (table_pg_osd_config_handler *)mst_config_table[PG_OSD_TABLE];
}

table_pg_log_manager_handler *db_table_manager::get_pg_log_manager_handler()
{
    return (table_pg_log_manager_handler *)mst_config_table[PGLOGMANAGER_TABLE];
}

table_video_record_file_handler *db_table_manager::get_video_record_file_handler()
{
    return (table_video_record_file_handler *)mst_config_table[VIDEO_RECORDFILE_TABLE];
}

table_picture_record_file_handler *db_table_manager::get_picture_record_file_handler()
{
    return (table_picture_record_file_handler *)mst_config_table[JPG_RECORDFILE_TABLE];
}

table_user_manager_handler *db_table_manager::get_user_manager_handler()
{
    return (table_user_manager_handler *)mst_config_table[USER_MANAGER_TABLE];
}

table_preset_text_handler *db_table_manager::get_preset_text_handler()
{
    return (table_preset_text_handler *)mst_config_table[PRESET_TEXT_TABLE];
}

void db_table_manager::uninit()
{
    for( int i = 0; i < MAX_TABLE; ++i ){
        delete mst_config_table[i];
    }

    memset( mst_config_table, 0x00, sizeof(mst_config_table) );
    close_all_databases();
}

bool db_table_manager::disconnect_db_file( const int i_connect_id )
{
    sql_executor_cmd *p_conn = get_db_executor( i_connect_id );
    if( NULL == p_conn ){
        return false;
    }

    bool b_ret = p_conn->close();
    delete p_conn;

    std::lock_guard<std::mutex> guard(m_connect_lock);
    m_connect_info_map.erase( i_connect_id );

    return b_ret;
}

bool db_table_manager::close_all_databases()
{
    std::lock_guard<std::mutex> guard(m_connect_lock);
    std::map<int, st_db_connect_info>::iterator it_conn_info = m_connect_info_map.begin();
    while(it_conn_info != m_connect_info_map.end()) {
        st_db_connect_info &tmp = it_conn_info->second;
        if(tmp.p_db_executor) {
            tmp.p_db_executor->close();
            delete tmp.p_db_executor;
        }

        it_conn_info++;
    }

    m_connect_info_map.clear();
    mi_connect_id = 0;

    return true;
}

bool db_table_manager::check_table_info( const int i_connect_id, const st_sql_table_info &table_info )
{
    if( table_info.str_table_name.empty() || table_info.col_info_list.empty() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "table name invalid or column none.\n" );
        return false;
    }

    bool b_find = false;
    st_db_connect_info *st_conn_info = NULL;

    if(i_connect_id > 0) {
        std::lock_guard<std::mutex> guard(m_connect_lock);
        std::map<int, st_db_connect_info>::iterator it = m_connect_info_map.find( i_connect_id );
        if( it == m_connect_info_map.end() ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "table_verify get conn id Failed. conn_id = %d\n", i_connect_id );
        } else {
            st_conn_info = &(it->second);
        }
    } else {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "[%s]: connect id invalid %d.\n", __func__, i_connect_id);
    }

    if(st_conn_info == NULL) {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "can not find connec info by connect id=%d\n", i_connect_id);
        return false;
    }

    std::list<st_sql_table_info>::iterator it_tbl = st_conn_info->db_table_info_list.begin();
    for( ; it_tbl != st_conn_info->db_table_info_list.end(); ++it_tbl ){
        if( table_info.str_table_name == it_tbl->str_table_name ){
            b_find = true;

            std::list<sql_column_info> col_list_tmp = table_info.col_info_list;
            std::list<sql_column_info> tbl_col_list = it_tbl->col_info_list;

            std::list<sql_column_info>::iterator it_col = col_list_tmp.begin();
            while( it_col != col_list_tmp.end() ){
                bool b_col_find = false;
                std::list<sql_column_info>::iterator it_tbl_col = tbl_col_list.begin();
                for( ; it_tbl_col != tbl_col_list.end(); ++it_tbl_col ){
                    if( it_col->mstr_name == it_tbl_col->mstr_name ){
                        b_col_find = true;
                        break;
                    }
                }

                if( b_col_find ){
                    it_col = col_list_tmp.erase( it_col );
                } else {
                    ++it_col;
                }
            }

            if( col_list_tmp.empty() ){
                return true;
            }

            it_col = col_list_tmp.begin();
            for( ; it_col != col_list_tmp.end(); ++it_col ){
                sql_update_table_command creator( table_info.str_table_name );
                creator.fill_item_field( *it_col );
                std::string str_sql = creator.create_sql_statement();
                HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "modify table structure, %s\n", str_sql.c_str() );
                sql_executor_cmd* p_executor = get_db_executor(i_connect_id);
                int i_result = 0;
                if( !p_executor->executor_cmd( str_sql, i_result ) ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "table_verify executor_sql Failed.\n" );
                    return false;
                }
            }
        }
    }

    if( !b_find ){
        sql_create_table_command tbl_creator( table_info.str_table_name );
        std::list<sql_column_info>::const_iterator it_col = table_info.col_info_list.begin();
        for( ; it_col != table_info.col_info_list.end(); ++it_col ){
            tbl_creator.fill_item_field( *it_col );
        }

        std::string str_sql = tbl_creator.create_sql_statement();
        HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "Create Table:%s\n", str_sql.c_str() );
        sql_executor_cmd* p_excutor = get_db_executor(i_connect_id);
        int i_result = 0;
        if( !p_excutor->executor_cmd( str_sql, i_result ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "table_verify executor_sql Failed.\n" );
            return false;
        }
    }

    return true;
}

sql_executor_cmd *db_table_manager::get_db_executor( const int i_connect_id )
{
    std::lock_guard<std::mutex> guard(m_connect_lock);
    std::map<int, st_db_connect_info>::iterator it = m_connect_info_map.find( i_connect_id );
    if( it == m_connect_info_map.end() ){
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "get_db_patch get connect id Failed. conn_id=%d\n", i_connect_id );
        return false;
    }

    return (it->second).p_db_executor;
}
